package com.atguigu.ggkt.order.service.impl;


import com.atguigu.ggkt.client.activity.CouponInfoFeignClient;
import com.atguigu.ggkt.client.couser.CourseFeignClient;
import com.atguigu.ggkt.client.user.UserInfoFeignClient;
import com.atguigu.ggkt.exception.GgktException;
import com.atguigu.ggkt.model.activity.CouponInfo;
import com.atguigu.ggkt.model.order.OrderDetail;
import com.atguigu.ggkt.model.order.OrderInfo;
import com.atguigu.ggkt.model.user.UserInfo;
import com.atguigu.ggkt.model.vod.Course;
import com.atguigu.ggkt.order.mapper.OrderInfoMapper;
import com.atguigu.ggkt.order.service.OrderDetailService;
import com.atguigu.ggkt.order.service.OrderInfoService;
import com.atguigu.ggkt.utils.AuthContextHolder;
import com.atguigu.ggkt.utils.OrderNoUtils;
import com.atguigu.ggkt.vo.order.OrderFormVo;
import com.atguigu.ggkt.vo.order.OrderInfoQueryVo;
import com.atguigu.ggkt.vo.order.OrderInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 订单表 订单表 服务实现类
 * </p>
 *
 * @author sleephardzz
 * @since 2023-07-21
 */
@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {

    //订单详情
    @Autowired
    private OrderDetailService orderDetailService;


    @Autowired
    private CourseFeignClient courseFeignClient;
    @Autowired
    private CouponInfoFeignClient couponInfoFeignClient;
    @Autowired
    private UserInfoFeignClient userInfoFeignClient;

    //生成订单方法submitOrder
    @Override
    public Long submitOrder(OrderFormVo orderFormVo) {
        //1获取生成订单条件值
        Long courseId = orderFormVo.getCourseId();
        Long couponId = orderFormVo.getCouponId();
        /** 针对当前用户 */
        Long userId = AuthContextHolder.getUserId();
        //2判断当前用户是否已经生成订单
//        用户id、课程id
        LambdaQueryWrapper<OrderDetail> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isEmpty(courseId), OrderDetail::getCourseId, courseId)
                .eq(StringUtils.isEmpty(userId), OrderDetail::getUserId, userId);
        OrderDetail orderDetailExists = orderDetailService.getOne(wrapper);
        if (orderDetailExists != null) {
            return orderDetailExists.getId();//订单已经存在了，直接返回订单id
        }
        //3 根据课程id查询课程信息
        Course course = courseFeignClient.getById(courseId);
        if (course == null) {
            throw new GgktException(20001, "课程不存在");
        }
        //4根据用户id查询用户信息
        UserInfo userInfo = userInfoFeignClient.getById(userId);
        if (userInfo == null) {
            throw new GgktException(20001, "用户不存在");
        }
        //5 根据优惠券id查询优惠券信息【可能没有】
        //优惠券金额
        BigDecimal couponReduce = new BigDecimal(0);
        if (couponId != null) {
            CouponInfo couponInfo = couponInfoFeignClient.getById(couponId);
            couponReduce = couponInfo.getAmount();
        }
        //6封装订单生成需要数据到对象，完成添加订单
        //6.1封装到orderinfo中
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setUserId(userId);
        orderInfo.setNickName(userInfo.getNickName());
        orderInfo.setPhone(userInfo.getPhone());
        orderInfo.setProvince(userInfo.getProvince());
        orderInfo.setOriginAmount(course.getPrice());
        orderInfo.setCouponReduce(couponReduce);
        orderInfo.setFinalAmount(orderInfo.getOriginAmount().subtract(orderInfo.getCouponReduce()));
        //订单号工具来
        orderInfo.setOutTradeNo(OrderNoUtils.getOrderNo());
        orderInfo.setTradeBody(course.getTitle());
        orderInfo.setOrderStatus("0");
        //存入数据库
        baseMapper.insert(orderInfo);
        //6.2封装到orderdetail中
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setOrderId(orderInfo.getId());
        orderDetail.setUserId(userId);
        orderDetail.setCourseId(courseId);
        orderDetail.setCourseName(course.getTitle());
        orderDetail.setCover(course.getCover());
        orderDetail.setOriginAmount(course.getPrice());
        orderDetail.setCouponReduce(new BigDecimal(0));
        orderDetail.setFinalAmount(orderDetail.getOriginAmount().subtract(orderDetail.getCouponReduce()));
        //存入数据库
        orderDetailService.save(orderDetail);
        //7更新优惠卷状态
        if (null != orderFormVo.getCouponUseId()) {
            //不为null，则远程调用
            couponInfoFeignClient.updateCouponInfoUseStatus(orderFormVo.getCouponUseId(), orderInfo.getId());
        }
        //8返回订单id
        return orderInfo.getId();
    }

    //   //获取订单信息方法
    @Override
    public OrderInfoVo getOrderInfoById(Long id) {
        OrderInfo orderInfo = baseMapper.selectById(id);
        OrderDetail orderDetail = orderDetailService.getById(id);

        //封装到vo中
        OrderInfoVo orderInfoVo = new OrderInfoVo();
        BeanUtils.copyProperties(orderInfo, orderInfoVo);
        orderInfoVo.setCourseId(orderDetail.getCourseId());
        orderInfoVo.setCourseName(orderDetail.getCourseName());
        return orderInfoVo;
    }

    //更改订单状态，处理支付结果
    @Override
    public void updateOrderStatus(String out_trade_no) {
        //1查订单
        LambdaQueryWrapper<OrderInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(!StringUtils.isEmpty(out_trade_no), OrderInfo::getOutTradeNo, out_trade_no);
        OrderInfo orderInfo = baseMapper.selectOne(wrapper);
        //2更新这个订单的状态
        orderInfo.setOrderStatus("1");
        //3mysql更新
        baseMapper.updateById(orderInfo);
    }

    //订单列表
    @Override
    public Map<String, Object> selectOrderInfoPage(Page<OrderInfo> pageParam,
                                                   OrderInfoQueryVo orderInfoQueryVo) {
        //orderInfoQueryVo获取查询条件
//        Long userId = orderInfoQueryVo.getUserId();
//        String outTradeNo = orderInfoQueryVo.getOutTradeNo();
//        String phone = orderInfoQueryVo.getPhone();
//        String createTimeEnd = orderInfoQueryVo.getCreateTimeEnd();
//        String createTimeBegin = orderInfoQueryVo.getCreateTimeBegin();
//        Integer orderStatus = orderInfoQueryVo.getOrderStatus();
        //判断条件值是否为空，不空，进行条件封装
        LambdaQueryWrapper<OrderInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(!StringUtils.isEmpty(orderInfoQueryVo.getUserId()), OrderInfo::getUserId, orderInfoQueryVo.getUserId());
        wrapper.eq(!StringUtils.isEmpty(orderInfoQueryVo.getOutTradeNo()), OrderInfo::getUserId, orderInfoQueryVo.getOutTradeNo());
        wrapper.eq(!StringUtils.isEmpty(orderInfoQueryVo.getPhone()), OrderInfo::getUserId, orderInfoQueryVo.getPhone());
        //大于等于开始时间
        wrapper.ge(!StringUtils.isEmpty(orderInfoQueryVo.getCreateTimeBegin()), OrderInfo::getUserId, orderInfoQueryVo.getCreateTimeBegin());
        //小于等于结束时间
        wrapper.le(!StringUtils.isEmpty(orderInfoQueryVo.getCreateTimeEnd()), OrderInfo::getUserId, orderInfoQueryVo.getCreateTimeEnd());
        wrapper.eq(!StringUtils.isEmpty(orderInfoQueryVo.getOrderStatus()), OrderInfo::getUserId, orderInfoQueryVo.getOrderStatus());
        /** 调用实现条件分页查询 */
        Page<OrderInfo> orderInfoPage = baseMapper.selectPage(pageParam, wrapper);
        long totalCount = orderInfoPage.getTotal();//总记录数
        long pagesCount = orderInfoPage.getPages();//总页数
        List<OrderInfo> records = orderInfoPage.getRecords();//**订单对象集合
        //订单里包含详情内容，根据订单id获取详情
        records.stream().forEach(orderInfo -> {
            this.getOrderDetail(orderInfo);
        });

        //封装到map
        Map<String, Object> map = new HashMap<>();
        map.put("total", totalCount);
        map.put("pageCount", pagesCount);
        map.put("records", records);
        return map;
    }


    private OrderInfo getOrderDetail(OrderInfo orderInfo) {
        Long id = orderInfo.getId();//订单id
        OrderDetail orderDetail = orderDetailService.getById(id);
        if (!StringUtils.isEmpty(orderDetail)) {
            String courseName = orderDetail.getCourseName();
            /** 通过orderInfo的属性，再给orderDetail封装回去 */
            orderInfo.getParam().put("courseName", courseName);
        }
        return orderInfo;
    }
}
